import concurrent.futures
import logging
import os
import sys
import traceback

from absl import app, flags

from coin.base.datetime_util import (convert_string_to_dates, iterate_date)
from coin.experimental.xguo.order_and_feed_stats.app.order_event_dumper import launch
from coin.experimental.xguo.order_and_feed_stats.app.og_event_config import og_log_config

FLAGS = flags.FLAGS


def main(_):
  start_date = FLAGS.start_date
  end_date = FLAGS.end_date
  root_dir = os.path.expanduser(FLAGS.root_dir)
  order_event_dir = FLAGS.order_event_dir
  max_workers = FLAGS.max_workers
  assert start_date, '--start_date must be specified.'
  assert end_date, '--end_date must be specified.'

  start_date = convert_string_to_dates(start_date)[0]
  end_date = convert_string_to_dates(end_date)[0]
  trading_dates = [td for td in iterate_date(start_date, end_date)]

  future_list = []
  with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
    for config in og_log_config:
      exchange = config['exchange']
      market_type = config['market_type']
      machine = config['machine']
      owner = config['owner']
      assert market_type in ['Spot', 'Futures', 'Margin'], market_type
      for trading_date in trading_dates:
        print('Running for %s %s %s %s %s...' %
              (exchange, market_type, machine, owner, trading_date))
        sys.stdout.flush()
        future = executor.submit(launch,
                                 exchange,
                                 trading_date,
                                 root_dir,
                                 machine,
                                 market_type,
                                 owner,
                                 order_event_dir)
        future_list.append((future, trading_date, config))

  for future, trading_date, config in future_list:
    try:
      future.result()
    except Exception as e:
      print('Fail to dump order event.', trading_date, config)
      print(traceback.format_exc())


if __name__ == '__main__':
  flags.DEFINE_string('start_date', None, 'yyyymmdd')

  flags.DEFINE_string('end_date', None, 'yyyymmdd. Feed at end_date is not checked.')

  flags.DEFINE_string('root_dir', '~/data/og_proto_log', 'root_dir.')

  flags.DEFINE_string('order_event_dir', 'order_event', 'order_event_dir.')

  flags.DEFINE_integer('max_workers', 12, '')

  logging.basicConfig(level='DEBUG', format='%(levelname)8s %(asctime)s %(name)s] %(message)s')
  app.run(main)
